package cn.wps.solution.demo.service;

import cn.wps.solution.demo.entity.File;
import cn.wps.solution.demo.entity.User;
import cn.wps.solution.demo.repository.FileRepository;
import cn.wps.solution.demo.repository.UserRepository;
import cn.wps.solution.weboffice.provider.v3.exception.FileNotExist;
import cn.wps.solution.weboffice.provider.v3.exception.FileUploadNotComplete;
import cn.wps.solution.weboffice.provider.v3.model.DigestType;
import cn.wps.solution.weboffice.provider.v3.model.FileInfo;
import cn.wps.solution.weboffice.provider.v3.model.FileUploadMultiPhase;
import cn.wps.solution.weboffice.provider.v3.service.MultiPhaseFileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class MultiPhaseFileStorageServiceImpl implements MultiPhaseFileStorageService {
    @Value("${weboffice.provider.host:http://localhost:8080}")
    private String host;

    @Autowired
    private PreviewServiceImpl previewService;
    @Autowired
    private FileRepository fileRepository;
    @Autowired
    private UserRepository userRepository;

    @Override
    public List<DigestType> uploadPrepare(String s) {
        return Collections.singletonList(DigestType.SHA1);
    }

    @Override
    public FileUploadMultiPhase.FileUploadAddress.Response uploadAddress(FileUploadMultiPhase.FileUploadAddress.Request request) {
        // TODO liangzuobin supports create new file, which no file id in request

        // ATTENTION
        // ConsoleController.upload() handle the upload request
        // and store the new content of file, and create a new version of file
        // without invoke uploadComplete method
        // it is not good in the real world
        return FileUploadMultiPhase.FileUploadAddress.Response.builder()
                .method(FileUploadMultiPhase.FileUploadAddress.Response.Method.PUT)
                .url(String.format("%s/console/upload/%s", host, request.getFileId()))
                .build();
    }

    @Override
    public FileInfo uploadComplete(FileUploadMultiPhase.FileUploadComplete.Request request) {
        // emm
        Optional.ofNullable(request)
                .map(FileUploadMultiPhase.FileUploadComplete.Request::getResponse)
                .filter(r -> r.getStatus() == HttpStatus.OK.value())
                .ifPresentOrElse(r -> {
                }, FileUploadNotComplete::new);

        User user = previewService.fetchUserByToken();

        return Optional.ofNullable(previewService.fetchFile(request.getFileId()))
                .map(f -> File.builder()
                        .id(f.getId().copyForNewVersion())
                        .name(request.getRequest().getName())
                        .size(request.getRequest().getSize())
                        .createTime(f.getCreateTime())
                        .modifyTime(LocalDateTime.now())
                        .creator(f.getCreator())
                        .modifier(user)
                        .build())
                .map(f -> fileRepository.save(f))
                .map(File::toFileInfo)
                .orElseThrow(FileNotExist::new);
    }
}
